import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
  Logger,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Request, Response } from 'express';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  private readonly logger = new Logger(LoggingInterceptor.name);

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const ctx = context.switchToHttp();
    const request = ctx.getRequest<Request>();
    const response = ctx.getResponse<Response>();
    const { method, url, body, query, params } = request as {
      method: string;
      url: string;
      body?: Record<string, any>;
      query: Record<string, any>;
      params: Record<string, any>;
    };
    const userAgent = request.get('User-Agent') || '';
    const ip = request.ip || request.connection.remoteAddress;

    const startTime = Date.now();

    // 记录请求信息
    this.logger.log(
      `请求开始: ${method} ${url} - IP: ${ip} - UserAgent: ${userAgent}`,
    );

    // 记录请求参数（排除敏感信息）
    if (Object.keys(query).length > 0) {
      this.logger.debug(`查询参数: ${JSON.stringify(query)}`);
    }
    if (Object.keys(params).length > 0) {
      this.logger.debug(`路径参数: ${JSON.stringify(params)}`);
    }
    if (body && Object.keys(body).length > 0) {
      // 过滤敏感字段
      const filteredBody = this.filterSensitiveData(body);
      this.logger.debug(`请求体: ${JSON.stringify(filteredBody)}`);
    }

    return next.handle().pipe(
      tap({
        next: (data) => {
          const endTime = Date.now();
          const duration = endTime - startTime;
          const statusCode = response.statusCode;

          this.logger.log(
            `请求完成: ${method} ${url} - 状态码: ${statusCode} - 耗时: ${duration}ms`,
          );

          // 记录响应数据（仅在调试模式下）
          if (process.env.NODE_ENV === 'development' && data) {
            const filteredData = this.filterSensitiveData(
              data as Record<string, any>,
            );
            this.logger.debug(`响应数据: ${JSON.stringify(filteredData)}`);
          }
        },
        error: (error: { message: string }) => {
          const endTime = Date.now();
          const duration = endTime - startTime;
          const statusCode = response.statusCode || 500;

          this.logger.error(
            `请求失败: ${method} ${url} - 状态码: ${statusCode} - 耗时: ${duration}ms - 错误: ${error.message}`,
          );
        },
      }),
    );
  }

  private filterSensitiveData(data: Record<string, any>): Record<string, any> {
    if (!data || typeof data !== 'object') {
      return data;
    }

    const sensitiveFields = ['password', 'token', 'secret', 'key', 'auth'];
    const filtered = { ...data };

    for (const field of sensitiveFields) {
      if (field in filtered) {
        filtered[field] = '***';
      }
    }

    // 递归处理嵌套对象
    for (const key in filtered) {
      if (typeof filtered[key] === 'object' && filtered[key] !== null) {
        filtered[key] = this.filterSensitiveData(
          filtered[key] as Record<string, any>,
        );
      }
    }

    return filtered;
  }
}
